#ifndef __ApeBattleMode_H__
#define __ApeBattleMode_H__

#include "Helper.h"
#include "CPlayer.h"
#include "CCamera.h"
#include "GameSystemManager.h"
#include "GameSceneManager.h"

class GameFrameListener : public InputListener
{
private:
	//Ogre::Timer timer;
	String cfgUser;
	String cfgPass;
	String cfgLocalPort;

	Projectile *arrow;
	PlayerMoves *playerMovement;

	//My stuff
	Player* mPlayer;
    //bool mShutdownRequested;
	
	//unsigned short mGameState;

	Vector3 camPos;

	/*
	OgreText *debug5,*debug6,*debug7,*debug8,*debug9,*debug10,*debug11,*debug12,*debug13,*debug14,*debug15;
	OgreText *debug16,*debug17,*debug18,*debug19;
	*/

	//Ogre stuff
	Radian camPitch, camYaw;
	Radian camYawAdd;
	Real timeScale;
	
	Vector3 trans;
	//Vector3 *ptrans;

	Quaternion quatOrientation;
	//Quaternion *pquatOrientation;

	unsigned long currentTime;
	//unsigned long posTime;

	bool player_moving;
	bool key_down;
	bool key_up;
	bool key_trigger;

	SceneManager* mSceneMgr;
	Root *mRoot;
   
	//Custom Caelum class
	//SkyGenerator *sky;
	
	//Custom PagedGeometry class
	//myPagedGeometry *mPagedGeometry;

	//Create my CEGUI Class
	myCEGUI *mCEGUI;
	

	RakNetClient *mRakNetClient;
	
	SceneNode* enemyNode;
	
	Ogre::Timer timer;

	bool isWriting;

	/////////////////////////////////
	Camera* mCamera;
	Viewport *viewport;
	Vector3 mTranslateVector;
	float mMoveScale;
	Degree mRotScale;

	Ogre::SceneNode *cameraNode;
	Ogre::SceneNode *groundNode;
	Ogre::SceneNode *cameraYawNode;
	Ogre::SceneNode *cameraPitchNode;
	Ogre::SceneNode *cameraRollNode;
	/////////////////////////////////
	
	ProjectileManager *pm;

	GameState *mGameState;
	//////////////NxOgre objects
	////////////////////////
	
	//myGamePhysx *mPhysxEngine;
	//myNxOgre *mPhysx;
	//myScythe *PhysicsSystem;
	myNxPhysx *myPhysics;

	myTerrain *myTerrainEditor;

	GameObjectManager *mGOManager;
	

public:
    GameFrameListener(RenderWindow* win, Camera* cam, SceneManager* mSM, Root* myRoot,GameState *mGS)
        : InputListener(), 
		  mSceneMgr(mSM),
		  mRoot(myRoot),
		  mGameState(mGS)
    {

		//initialize camera
		createCamera();
		
		//GameSceneManager::getSingleton()->startScene(mRoot,mCamera,viewport,mSceneMgr,mWindow);
		
		//GameSystemManager::getSingleton()->setSingleton(mSceneMgr,mCamera,mWindow,gameState,mMouse,mKeyboard);
		//GameSystemManager::getSingleton()->
		
		myTerrainEditor = new myTerrain(mSceneMgr,mCamera);
		myTerrainEditor->loadTerrain();
		
		myPhysics = new myNxPhysx(mSceneMgr);
		myPhysics->createTerrainActor(myTerrainEditor->getTerrainManager());
		
		//myNxPhysx::initNxPhysx(mSceneMgr);
		//myNxPhysx::getSingleton()->createTerrainActor(myTerrainEditor->getTerrainManager());

		mTranslateVector = Vector3(Vector3::ZERO);
	
		//GameSystemManager::setSingleton(mSceneMgr,mCamera,mWindow,mGameState,mMouse,mKeyboard);
		

		GameObjectManager *mGameManager = new GameObjectManager();

		mGameManager->createObject("Hola");

		//ApeComponent::GameObject *GO = new ApeComponent::GameObject((std::string)"Camera");
		//ApeComponent::GameObject *GO = new ApeComponent::GameObject((std::string)"Camera");
		//ApeComponent::GameObject *GO = new ApeComponent::ObjTemplateMgr::createObject((std::string)"Camera");
		//ApeComponent::GameObject *GO = ApeComponent::ObjTemplateMgr::getInstance()->createObject((std::string)"Camera");
		
		//CCamera *myCamera = new CCamera();
		
		//ApeComponent::CompTemplateMgr::getInstance()->registerComponent(myCamera);
		//GO->setComponent(ApeComponent::CompTemplateMgr::getInstance()->createCompFromTemplate((std::string)"CCamera"));

		//GO->setComponent(ApeComponent::CompTemplateMgr::getInstance()->createComp((std::string)"CCamera"));
		//GO = dynamic_cast<GOCamera*>(ApeComponent::CompTemplateMgr::getInstance()->createComp("CCamera"));
		
		//ObjTemplateMgr *GOMgr = new ApeComponent::ObjTemplateMgr();

		

		
		//myCamera = dynamic_cast<CCamera*>();
		//std::string a;
		//a = "CCamera";
		
		
		
		//myCamera =dynamic_cast<CCamera*>ApeComponent::CompTemplateMgr::getInstance()->createComp(a);
		

		/*
		debug5 = new OgreText("debug5");
		debug6 = new OgreText("debug6");
		debug7 = new OgreText("debug7");
		debug8 = new OgreText("debug8");
		debug9 = new OgreText("debug9");
		debug10 = new OgreText("debug10");
		debug11 = new OgreText("debug11");
		debug12 = new OgreText("debug12");
		debug13 = new OgreText("debug13");
		debug14 = new OgreText("debug14");

		debug15 = new OgreText("debug15");
		debug16 = new OgreText("debug16");
		debug17 = new OgreText("debug17");
		debug18 = new OgreText("debug18");
		debug19 = new OgreText("debug19");
		*/

		camYawAdd = 0;

		//showDebugOverlay(false);

		//Create paged geometry system
		//mPagedGeometry = new myPagedGeometry(mCamera,mSceneMgr);
		//mPagedGeometry->createPagedGeometry();
		
		//Load settings from resources.cfg and the group [Client]
		loadClientSettings();

		//Create and setup CEGUI
		mCEGUI = new myCEGUI(mWindow,mSceneMgr,mGameState,mMouse,mKeyboard);
		//mCEGUI->createGUI();
		setupGUI_EventHandlers();
		mCEGUI->UpdateState();
		//setupGUI_EventHandlers2();

		//Player Class
		mPlayer = new Player();
 
		//Create and setup Caelum System
		//sky = new SkyGenerator(mWindow,mRoot,mSceneMgr);
		//sky->setupCaelum();

		Entity *ent;
		ent = mSceneMgr->createEntity("arrow", "arrow.mesh"); //remember to load before calling Projectile Manager

		//Projectile Manager Class
		pm = new ProjectileManager(mSceneMgr,ent,30);
		
		playerMovement = new PlayerMoves();

		//Create client network
		mRakNetClient = new RakNetClient(mSceneMgr); //textQueueList

		player_moving = false;
		key_down = false;
		key_up = false;
		key_trigger = false;
		isWriting = false;

		//mPhysxEngine = new myGamePhysx();
		//mPhysx = new myNxOgre(mSceneMgr);
		//mPhysx->createPhysics();
		//PhysicsSystem = new myScythe(
		//CreateScythe(

		loadClientSettings();

		//mGameState = GAME_STATE_PLAYING;
		
		

	}

	void loadClientSettings()
	{
		ConfigFile cf;
		cf.load("resources.cfg");
		cfgUser = cf.getSetting("User","Client");
		cfgPass = cf.getSetting("Pass","Client");
		cfgLocalPort = cf.getSetting("LocalPort","Client");
	}

	void setupGUI_EventHandlers(void)
    {
		
		mCEGUI->getElement("Menu/btnExit")->subscribeEvent(CEGUI::PushButton::EventClicked, // EventClicked
				CEGUI::Event::Subscriber(&GameFrameListener::handleGUI_Quit, this));
		
		mCEGUI->getElement("Menu/btnConnect")->subscribeEvent(CEGUI::PushButton::EventClicked,
			CEGUI::Event::Subscriber(&GameFrameListener::handleGUI_Connect, this));
		
		//CEGUI::Editbox* editBox = (CEGUI::Editbox*)CEGUI::WindowManager::getSingleton().getWindow("Menu/txtUser");
		//editBox->setText(cfgUser);
		//editBox = (CEGUI::Editbox*)CEGUI::WindowManager::getSingleton().getWindow("Menu/txtPass");
		//editBox->setText(cfgPass);
		//editBox = (CEGUI::Editbox*)CEGUI::WindowManager::getSingleton().getWindow("Menu/txtCP");
		//editBox->setText(cfgLocalPort);

	}
	
	//void setupGUI_EventHandlers2(void)
    //{
		//mCEGUI->registerEventHandler(&GameFrameListener::handleGUI_Quit, this);

		/*
		CEGUI::WindowManager& wmgr = CEGUI::WindowManager::getSingleton();
        wmgr.getWindow((CEGUI::utf8*)"Menu/btnExit")
			->subscribeEvent(
			CEGUI::PushButton::EventClicked, // EventClicked
				CEGUI::Event::Subscriber(&GameFrameListener::handleGUI_Quit, this));
		*/
		/*
		wmgr = CEGUI::WindowManager::getSingleton();
        wmgr.getWindow((CEGUI::utf8*)"Menu/btnConnect")
			->subscribeEvent(
			CEGUI::PushButton::EventClicked, // EventClicked
			CEGUI::Event::Subscriber(&GameFrameListener::handleGUI_Connect, this)); //TutorialApplication
		*/
	//}

	~GameFrameListener()
	{
		mRoot->destroySceneManager(mSceneMgr);

		delete myPhysics;
		//delete mPagedGeometry;
		//delete sky;
		delete myTerrainEditor;

		mWindow->removeViewport(0);

		//delete mCamera;
		delete mPlayer;
		delete mCEGUI;
		delete mRakNetClient;
		
	}

	bool handleGUI_Connect(const CEGUI::EventArgs& e)
    {
		//mRakNetClient->Connect( mCEGUI->EditBoxToChr("Menu/txtCP"),mCEGUI->EditBoxToChr("Menu/txtIP"),mCEGUI->EditBoxToChr("Menu/txtSP") );
		mRakNetClient->Connect(mCEGUI->EditBoxToChr("Menu/txtCP"),mCEGUI->EditBoxToChr("Menu/txtIP"),mCEGUI->EditBoxToChr("Menu/txtSP"),mCEGUI->EditBoxToChr("Menu/txtUser"),mCEGUI->EditBoxToChr("Menu/txtPass") );
		return true;
    }

	bool handleGUI_Quit(const CEGUI::EventArgs& e)
    {
		//mRakNetClient->Disconnect();
		//requestShutdown();
		mGameState->setGameState(GameState::SWITCH_MODE_OFF);
		mGameState->setGameState(GameState::SHUTDOWN);
        return true;
    }
	
	bool frameStarted(const FrameEvent& evt)
	{

		//if (mKeyboard->isKeyDown(OIS::KC_AT) && mKeyboard->isKeyDown(OIS::KC_F4))
		//	return false;

		if(mGameState->isShutdownRequested)
			return false;
		
		mCEGUI->UpdateGUI();

		//if(mGameState->isGUIEnable) {
			
			//CEGUI::System::getSingleton().injectMouseMove( ms.X.rel, ms.Y.rel );
			//CEGUI::MouseCursor::getSingleton().show();
		//	mCEGUI->mainWindow->setVisible(true);
		//}
		//else {
		//	CEGUI::MouseCursor::getSingleton().hide();
		//	mCEGUI->mainWindow->setVisible(false);
		//}

		if(!mWindow->isActive()) //This is to force rendering even if window is not visible (for testing clients)
			mWindow->setActive(true);
		
		myPhysics->Update(evt.timeSinceLastFrame);
		//myNxPhysx::getSingleton()->Update(evt.timeSinceLastFrame);
		//models[0]->getModelPos(0).x

		//debug17->showTextNormal("models[0]: " + StringConverter::toString(models[0]->getModelPos(0).x),300,330);
		//debug15->showTextNormal("arrow->currentPosition: " + StringConverter::toString(arrow->currentPosition),300,350);

		OgreQueueText::instance()->ShowText();

		//Capture events from mouse and keyboard
		mKeyboard->capture();
		mMouse->capture();

		//Get input from user and set camera variables
		getCameraKeyboardInput(evt.timeSinceLastFrame);
		getCameraMouseInput(evt.timeSinceLastFrame);

		//Update camera with user input
		//moveCamera();
		moveCamera();

		//Update variables to send to server each tick
		quatOrientation = cameraYawNode->getOrientation() * cameraPitchNode->getOrientation(); // cameraPitchNode->getOrientation()
		mRakNetClient->UpdateMyPlayer(cameraNode->getPosition(),mTranslateVector,quatOrientation);
		
		//Render pagedgeometry objects
		//mPagedGeometry->renderPagedGeometry();
		//Update Sky
		//sky->UpdateSun();
		
		mRakNetClient->ReceiveData();

		//Render players currently playing
		mRakNetClient->UpdatePlayers(evt.timeSinceLastFrame);

		//Render arrows shooted
		pm->showProjectiles(evt.timeSinceLastFrame);
		
		//Player physics
		if(playerMovement->status==1)
			playerMovement->performAction(evt.timeSinceLastFrame);

		//mPhysxEngine->SimulatePhysX(evt.timeSinceLastFrame);

		//debug17->showTextNormal("guy->head: " + StringConverter::toString(mPhysxEngine->guy->head->getGlobalPosition().y),300,330);
		//debug15->showTextNormal("arrow->currentPosition: " + StringConverter::toString(arrow->currentPosition),300,350);
		//debug16->showTextNormal("arrow->alpha: " + StringConverter::toString(arrow->alpha),350,370);
		//debug17->showTextNormal("arrow->gamma: " + StringConverter::toString(arrow->gamma),350,390);
		return true;
	}

	void getCameraKeyboardInput(Real time)
	{
		if(isWriting)
			return;

		if (mKeyboard->isKeyDown(OIS::KC_W))
			mTranslateVector.z = -0.1 * time * 390.0f; //390.0f
		if (mKeyboard->isKeyDown(OIS::KC_S))
			mTranslateVector.z = 0.1 * time * 390.0f;
		if (mKeyboard->isKeyDown(OIS::KC_D))
			mTranslateVector.x = 0.1 * time * 390.0f;
		if (mKeyboard->isKeyDown(OIS::KC_A))
			mTranslateVector.x = -0.1 * time * 390.0f;
		if (mKeyboard->isKeyDown(OIS::KC_E))
			mTranslateVector.y = 0.1 * time * 390.0f;
		if (mKeyboard->isKeyDown(OIS::KC_Q))
			mTranslateVector.y = -0.1 * time * 390.0f;
		return;
	}

	void getCameraMouseInput(Real time)
	{
		// Rotation factors, may not be used if the second mouse button is pressed
		// 2nd mouse button - slide, otherwise rotate
		const MouseState &ms = mMouse->getMouseState();
		//GameSystemManager::getSingleton()->getInput()->mRotX = Degree(-ms.X.rel * 0.3); //* time * 40
		//GameSystemManager::getSingleton()->getInput()->mRotY = Degree(-ms.Y.rel * 0.3); //* time * 40
		return;
	}
   
	void createCamera()
	{
		/*
		ST_GENERIC = 1,
		ST_EXTERIOR_CLOSE = 2,
		ST_EXTERIOR_FAR = 4,
		ST_EXTERIOR_REAL_FAR = 8,
		ST_INTERIOR = 16
		*/

		//mSceneMgr = mRoot->createSceneManager(ST_EXTERIOR_CLOSE);

		//mSceneMgr = mRoot->createSceneManager(ST_EXTERIOR_REAL_FAR);
		
		mSceneMgr = mRoot->createSceneManager("OctreeSceneManager", "ETInstance");

		//Ogre::ColourValue fogColor(0.93f, 0.86f, 0.76f);
		//mSceneMgr->setFog(Ogre::FOG_LINEAR, fogColor, 0.001f, 500.0f, 1000.0f); 

		//mSceneMgr = mRoot->createSceneManager("OctreeSceneManager", "ETInstance");

		//Set up lighting
		Light *light = mSceneMgr->createLight("Sun");
		light->setType(Light::LT_DIRECTIONAL); // LT_DIRECTIONAL
		light->setDirection(Vector3(0.0f, -0.5f, 1.0f));
		mSceneMgr->setAmbientLight(ColourValue(0.7, 0.7, 0.7));

		//HeightFunction::initialize(mSceneMgr);	
		
		

		//camNode->setPosition( 40, 300, 580 );
		Vector3 camp; // = mCamera->getPosition();
		camp.x = 600; //700
		camp.z = 300; //700
		camp.y = 280; //52 HeightFunction::getTerrainHeight(camp.x, camp.z) + 3;; //HeightFunction::getTerrainHeight(camp.x, camp.z) + 3;
		
		
		//Initialize the camera and viewport
		mCamera = mSceneMgr->createCamera("MainCamera");
		//mCamera->setPosition(camp);
		viewport = mWindow->addViewport(mCamera);
		viewport->setBackgroundColour(ColourValue(0.47f, 0.67f, 0.96f));	//Blue sky background color
		mCamera->setAspectRatio(Real(viewport->getActualWidth()) / Real(viewport->getActualHeight()));
		mCamera->setNearClipDistance(1.0f);
		mCamera->setFarClipDistance(1000.0f);
		
		// Create the camera's top node (which will only handle position).
		cameraNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
		cameraNode->setPosition(camp); //(0, 0, 500);

		// Create the camera's yaw node as a child of camera's top node.
		cameraYawNode = cameraNode->createChildSceneNode();

		// Create the camera's pitch node as a child of camera's yaw node.
		cameraPitchNode = cameraYawNode->createChildSceneNode();

		// Create the camera's roll node as a child of camera's pitch node
		// and attach the camera to it.
		cameraRollNode = cameraPitchNode->createChildSceneNode();
		cameraRollNode->attachObject(mCamera);

		
		//mCamera->setPolygonMode(PM_SOLID);
		//mCamera->setPolygonMode(PM_WIREFRAME);

		////////////////////////////////////////////////////////////////////////////////////////
		//mCamera->setPosition(Vector3(0,1,10));
		//mCamera->lookAt(Vector3(0,2,-300));
		/*
		Plane plane2( Vector3::UNIT_Y, 0 );
		MeshManager::getSingleton().createPlane("ground",
			ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane2,
			400,400,10,10,true,1,25,25,Vector3::UNIT_Z);

		*/
		
		Ogre::Entity* groundPlane = mSceneMgr->createEntity( "ninja", "ninja.mesh" );
		groundPlane->setMaterialName("concrete");
		//groundPlane->setCastShadows(false);
		
		//groundPlane->setCastShadows(false);

		groundNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
		groundNode->attachObject(groundPlane);
		groundNode->setPosition(Vector3(730,50,720));
		
		mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE);
		//SHADOWTYPE_STENCIL_ADDITIVE
		//SHADOWTYPE_TEXTURE_ADDITIVE
		//SHADOWTYPE_TEXTURE_MODULATIVE

		//mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(groundNode);
		////////////////////////////////////////////////////////////////////////////////////////




		//mSceneMgr->setWorldGeometry("Terrain.cfg");
		//createTerrain("Terrain.cfg");
	
	}

	void moveCamera()
	{
		Ogre::Real pitchAngle;
		Ogre::Real pitchAngleSign;

		if(mGameState->isGUIEnable)
			return;

		// Yaws the camera according to the mouse relative movement.
		//cameraYawNode->yaw(GameSystemManager::getSingleton()->getInput()->mRotX);
		

		// Pitches the camera according to the mouse relative movement.
		//cameraPitchNode->pitch(GameSystemManager::getSingleton()->getInput()->mRotY);

		//////////////////////////////////////////////////////////////////////////////////////////
		//////////////////////////////////////////////////////////////////////////////////////////
		// Translates the camera according to the translate vector which is
		// controlled by the keyboard arrows.
		//
		// NOTE: We multiply the mTranslateVector by the cameraPitchNode's
		// orientation quaternion and the cameraYawNode's orientation
		// quaternion to translate the camera accoding to the camera's
		// orientation around the Y-axis and the X-axis.
		//cameraNode->translate(cameraYawNode->getOrientation() *	cameraPitchNode->getOrientation() *	GameSystemManager::getSingleton()->getInput()->mTranslateVector,Ogre::SceneNode::TS_LOCAL);
		
		if(Soldier::soldiers.Size()>0) {
			//if(GameSystemManager::getSingleton()->getInput()->mTranslateVector==Vector3::ZERO)
			//	Soldier::mySoldier->State = IDLE;
			//else
			//	Soldier::mySoldier->State = WALKING;
		}
		
		Vector3 camp; // = mCamera->getPosition();
		camp.x = cameraNode->getPosition().x;
		//camp.y = HeightFunction::getTerrainHeight(cameraNode->getPosition().x, cameraNode->getPosition().z) + 3;
		camp.y = cameraNode->getPosition().y;
		camp.z = cameraNode->getPosition().z;
		cameraNode->setPosition(camp);
		
		//////////////////////////////////////////////////////////////////////////////////////////
		//////////////////////////////////////////////////////////////////////////////////////////

		// Angle of rotation around the X-axis.
		pitchAngle = (2 * Ogre::Degree(Ogre::Math::ACos(cameraPitchNode->getOrientation().w)).valueDegrees());

		// Just to determine the sign of the angle we pick up above, the
		// value itself does not interest us.
		pitchAngleSign = cameraPitchNode->getOrientation().x;

		// Limit the pitch between -90 degress and +90 degrees, Quake3-style.
		if (pitchAngle > 90.0f)
		{
			if (pitchAngleSign > 0)
				// Set orientation to 90 degrees on X-axis.
				cameraPitchNode->setOrientation(Ogre::Quaternion(Ogre::Math::Sqrt(0.5f),
																	   Ogre::Math::Sqrt(0.5f), 0, 0));
			else if (pitchAngleSign < 0)
				// Sets orientation to -90 degrees on X-axis.
				cameraPitchNode->setOrientation(Ogre::Quaternion(Ogre::Math::Sqrt(0.5f),
																	   -Ogre::Math::Sqrt(0.5f), 0, 0));
		}

		mTranslateVector = Ogre::Vector3::ZERO;
	}

	bool setupCamera()
	{
		//static Ogre::Timer timer;
		static unsigned long lastTime = 0;
		currentTime = timer.getMilliseconds();

		if(mPlayer->bIsTyping)
			return true;

		//Calculate the amount of time passed since the last frame
		timeScale = (currentTime - lastTime) * 0.001f;
		if (timeScale < 0.001f)
			timeScale = 0.001f;
		
		timeScale = timeScale * 10.0f;

		lastTime = currentTime;
		float terrY;
		
		trans = Vector3(0, 0, 0);
		//quatOrientation = Quaternion(0,0,0,0);
		//camYawAdd = 0;

		const OIS::MouseState &ms = mMouse->getMouseState();

		switch(mPlayer->Camera)
		{
		case mPlayer->CAMERA_MODE_NORMAL:
			//mDebugText = "CAMARA: FIRST_PERSON_EDITOR"; // + StringConverter::toString(mCameraTypee->mCameraType);
				
			if (mKeyboard->isKeyDown(OIS::KC_W))
				trans.z = -1;
			if (mKeyboard->isKeyDown(OIS::KC_S))
				trans.z = 1;
			if (mKeyboard->isKeyDown(OIS::KC_D))
				trans.x = 1;
			if (mKeyboard->isKeyDown(OIS::KC_A))
				trans.x = -1;
			if (mKeyboard->isKeyDown(OIS::KC_E))
				trans.y = 1;
			if (mKeyboard->isKeyDown(OIS::KC_Q))
				trans.y = -1;
			
			trans = trans * timeScale;
			mCamera->moveRelative(trans); // * timeScale
			
			mCamera->setOrientation(Quaternion::IDENTITY);
			mCamera->pitch(camPitch);
			mCamera->yaw(camYaw);
			
			camPos = mCamera->getPosition();
			//terrY = HeightFunction::getTerrainHeight(camPos.x, camPos.z);
			camPos.y = terrY + 3;

			//camPos = camPos * trans;
			mCamera->setPosition(camPos); // * trans * timeScale
			
			
			

			break;
		/*
		case mPlayer->FREE_CAMERA_EDITOR:
			//mDebugText = "CAMARA: FREE_CAMERA_EDITOR"; // + StringConverter::toString(mCameraTypee->mCameraType);
			if (mKeyboard->isKeyDown(OIS::KC_W))
				trans.z = -2;
			if (mKeyboard->isKeyDown(OIS::KC_S))
				trans.z = 1;
			if (mKeyboard->isKeyDown(OIS::KC_D))
				trans.x = 1;
			if (mKeyboard->isKeyDown(OIS::KC_A))
				trans.x = -1;
			if (mKeyboard->isKeyDown(OIS::KC_E))
				trans.y = 1;
			if (mKeyboard->isKeyDown(OIS::KC_Q))
				trans.y = -1;
			
			mCamera->moveRelative(trans * timeScale * 30.0f);
			
			mCamera->setOrientation(Quaternion::IDENTITY);
			mCamera->pitch(camPitch);
			mCamera->yaw(camYaw);
			
			camPos = mCamera->getPosition();
			terrY = HeightFunction::getTerrainHeight(camPos.x, camPos.z);
			//mDebugText = "Info debug: " + StringConverter::toString(terrY);
			
			if (camPos.y < terrY + 3 ){
				camPos.y = terrY + 3;
				mCamera->setPosition(camPos);
			}
			break;
		case mPlayer->THIRD_PERSON_EDITOR:
			//mDebugText = "CAMARA: THIRD_PERSON_EDITOR"; // + StringConverter::toString(mCameraTypee->mCameraType);
			break;
		case mPlayer->FIXED_POS_EDITOR:
			//mDebugText = "CAMARA: FIXED_POS_EDITOR"; // + StringConverter::toString(mCameraTypee->mCameraType);
			break;
		*/
		}
		return true;
	}
	
	bool mouseMoved( const OIS::MouseEvent &arg )
	{
		if(mPlayer->bIsTyping)
			return false;
		
		switch(mPlayer->Camera)
		{
		case mPlayer->CAMERA_MODE_NORMAL:
			camYawAdd = Radian(-arg.state.X.rel / 2000.0f);
			camYaw += Radian(-arg.state.X.rel / 2000.0f);
			camPitch += Radian(-arg.state.Y.rel / 2000.0f);
		}
		return true;
	}

	bool mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
	{
		//Aca!
		if(isWriting)
			return true;

		if(mGameState->isGUIEnable) {
			CEGUI::System::getSingleton().injectMouseButtonDown(mCEGUI->convertOISMouseButtonToCegui(id));
			return true;
		}

		if(id == 0) {
			pm->Shoot(cameraNode->getPosition(),cameraYawNode->getOrientation()*cameraPitchNode->getOrientation() * -Vector3::UNIT_Z ,0.4,5,cameraYawNode->getOrientation()*cameraPitchNode->getOrientation());
			//pm->Shoot(cameraNode->getPosition(),cameraYawNode->getOrientation()*cameraPitchNode->getOrientation()*mCamera->getDirection() ,2,14,cameraYawNode->getOrientation()*cameraPitchNode->getOrientation());
			if(Soldier::soldiers.Size() > 0)
				Soldier::mySoldier->Shooted = true;
		}
		if(id == 1) {
			
			//mPhysx->pArrow->setGlobalPosition(cameraNode->getPosition());
			//mPhysx->pArrow->setGlobalOrientation(cameraNode->getOrientation());
			//mPhysx->pArrow->setLinearVelocity(Vector3::ZERO);
			//mPhysx->pArrow->setAngularVelocity(Vector3::ZERO);
			//added
			//mPhysx->pArrow->setAngularMomentum(Vector3::ZERO);
			//mPhysx->pArrow->setLinearMomentum(Vector3::ZERO);
			//mPhysx->pArrow->addLocalForce(cameraYawNode->getOrientation()*cameraPitchNode->getOrientation() * -Vector3(0,0,1) * 15000);
			
		}
		//arrow->shoot(mCamera->getPosition(), mCamera->getDirection(),2,14,mCamera->getOrientation(),mCamera);

		CEGUI::System::getSingleton().injectMouseButtonDown(mCEGUI->convertOISMouseButtonToCegui(id));
		mPlayer->isClicking = true;
		return true;
	}

	bool mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
	{
		CEGUI::System::getSingleton().injectMouseButtonUp(mCEGUI->convertOISMouseButtonToCegui(id));
		mPlayer->isClicking = false;
		return true;
	}

	
	bool keyPressed( const OIS::KeyEvent &arg )
	{
		//mGameState->UpdateGameState(arg);

		if( arg.key == OIS::KC_ESCAPE) { //:KC_LSHIFT && arg.key == OIS::KC_Q
			if(mGameState->isGUIEnable) {
				mGameState->setGameState(GameState::DISABLE_GUI);
				mCEGUI->UpdateState();
			}
			else {
				mGameState->setGameState(GameState::ENABLE_GUI);
				mCEGUI->UpdateState();
			}
		}
		if ( arg.key == OIS::KC_F1 ) {
			mGameState->setGameState(GameState::SWITCH_MODE_ON);
			mGameState->setGameState(GameState::SET_BATTLE_MODE);
			mGameState->setGameState(GameState::SHUTDOWN);
		}
		if ( arg.key == OIS::KC_F2 ) {
			mGameState->setGameState(GameState::SWITCH_MODE_ON);
			mGameState->setGameState(GameState::SET_EDITOR_MODE);
			mGameState->setGameState(GameState::SHUTDOWN);
		}

		if ( arg.key == OIS::KC_RETURN )
			isWriting = !isWriting;
		
		if(arg.key == OIS::KC_F6) {
			showDebugOverlay();
		}

		if(arg.key == OIS::KC_F5) {
			if (mCamera->getPolygonMode() == PM_SOLID)
				mCamera->setPolygonMode(PM_WIREFRAME);
			else
				mCamera->setPolygonMode(PM_SOLID);
		}

		CEGUI::Editbox* objectEditBox = (CEGUI::Editbox*)CEGUI::WindowManager::getSingleton().getWindow("txtCmd");
		if(isWriting) {
			objectEditBox->activate();
			CEGUI::System::getSingleton().injectChar( arg.text );
			CEGUI::System::getSingleton().injectKeyDown( arg.key );
		}
		else
		{
			//if(strlen(objectEditBox->getText().c_str())>0)
			//		//mClientNetwork->SendChatMessage((char*)mCEGUI->EditBoxToChr("txtCmd"));
			objectEditBox->setText("");
			objectEditBox->deactivate();
			//if(arg.key == OIS::KC_SPACE)
			//	playerMovement->Jump(mCamera->getPosition(), mCamera->getDirection(),2,1,mCamera);
			
			CEGUI::System::getSingleton().injectKeyDown( arg.key );
		}
		return true;
	}
	

	bool keyDown( const OIS::KeyEvent &arg )
	{
		//debug15->showTextNormal("Keydown: " + StringConverter::toString(arg),350,350);
		return true;
	}
	//----------------------------------------------------------------//
	bool keyReleased( const OIS::KeyEvent &arg )
	{
		CEGUI::System::getSingleton().injectKeyUp( arg.key );
		return true;
	}
    void requestShutdown(void)
    {
        mShutdownRequested = true;
    }

};

#endif